import type { UserInfo } from '#/index';
import { LINK_HOME, LINK_LOGIN } from '@/router/constants';
import { loginByPw, loginBySms, logout, register } from '@/views/user/apis';
import { cleanPiniaStorage } from '@vc/utils';
import { defineStore } from 'pinia';
import message from 'vc/src/common/message';
import { useMultipleTabWithOut } from 'vc/src/store/multiple-tab';
import pinia from '../';
import { getUserInfo } from '@/views/user/apis';
import { router } from '@/router';
import { usePermissionStore } from '@/store/modules/permission';
import { type RouteRecordRaw } from 'vue-router';
import { PAGE_NOT_FOUND_ROUTE } from '@/router/constants';
import pkgJson from '../../../package.json';

/** 登录注册类型 */
export type LoginOrRegType = 'login' | 'loginPhone' | 'reg';

/** 用户状态数据 */
interface UserState {
  /** 用户信息 */
  userInfo: Nullable<UserInfo>;
  /** 用户 token */
  token?: string;
  /** 刷新的 token */
  refreshToken?: string;
}

export const useUserStore = defineStore({
  id: 'app-user',
  persist: {
    strategies: [
      {
        paths: ['userInfo', 'token', 'refreshToken']
      }
    ]
  },
  state: (): UserState => ({
    // 用户信息
    userInfo: null,
    // token 信息
    token: undefined,
    refreshToken: undefined
  }),
  getters: {
    // 获取用户信息
    getUserInfo(): UserInfo {
      return this.userInfo || ({} as UserInfo);
    },
    // 获取 token
    getToken(): string {
      return this.token as string;
    },
    // 获取 token
    getRefreshToken(): string {
      return this.refreshToken as string;
    }
  },
  actions: {
    // 设置用户 token
    setToken(info: string | undefined) {
      this.token = info ? info : ''; // for null or undefined value
    },
    // 设置用户 token
    setRefreshToken(info: string | undefined) {
      this.refreshToken = info ? info : ''; // for null or undefined value
    },
    resetState() {
      this.userInfo = null;
      this.setToken('');
      this.refreshToken = '';
    },
    /**
     * @description 登录处理
     */
    async loginOrReg(params, loginType: LoginOrRegType = 'login') {
      try {
        const isLogin = loginType === 'login';
        const isReg = loginType === 'reg';
        
        // 调用登录接口
        const data = isLogin ? await loginByPw(params) : isReg ? await register(params) : await loginBySms(params);
        
        if (data.code === 200) {
          if (isReg) {
            message.success({
              message: '注册成功，登录中...',
              duration: 2000
            });
          }
          const { accessToken, refreshToken } = data.data;
          this.setToken(accessToken);
          this.setRefreshToken(refreshToken);
          return this.afterLoginAction(isReg);
        } else {
          return Promise.reject(data);
        }
      } catch (error) {
        return Promise.reject(error);
      }
    },
    setUserInfo(info: UserInfo | null) {
      this.userInfo = info;
    },
    /**
     * @description 登录之后的一些逻辑
     */
    async afterLoginAction(isReg?: boolean) {
      if (!this.getToken) return null;
      const userInfo = await this.getUserInfoAction();
      const permissionStore = usePermissionStore();
      if (!permissionStore.isDynamicAddedRoute) {
        const routes = await permissionStore.buildRoutesAction();
        routes.forEach((route) => {
          router.addRoute(route as unknown as RouteRecordRaw);
        });
        router.addRoute(PAGE_NOT_FOUND_ROUTE as unknown as RouteRecordRaw);
        permissionStore.setDynamicAddedRoute(true);
      }
      
      async function goHomePage() {
        await router.replace(LINK_HOME);
      }
      
      const { query } = router.currentRoute.value;
      
      if (query?.redirect) {
        await router.replace(query.redirect as string);
      } else {
        if (isReg) {
          setTimeout(async () => {
            await goHomePage();
          }, 1000);
        } else {
          await goHomePage();
        }
      }
      return userInfo;
    },
    /**
     * @description 获取用户信息
     */
    async getUserInfoAction() {
      if (!this.getToken) return null;
      const userInfo = await getUserInfo();
      this.setUserInfo(userInfo);
      return userInfo;
    },
    async logout () {
      const { resetState } = useMultipleTabWithOut(pinia);
      resetState();
      cleanPiniaStorage(pkgJson);
      if (this.getRefreshToken) {
        await logout(this.getRefreshToken).finally(() => {
          resetState();
        }).finally(async () => {
          message.success('退出成功');
          this.setToken('');
          this.refreshToken = '';
          await router.replace(LINK_LOGIN);
        });
      }
    },
    resetGoLogin () {
      const { resetState } = useMultipleTabWithOut(pinia);
      resetState();
      cleanPiniaStorage(pkgJson);
      this.setToken('');
      this.refreshToken = '';
      router.replace(LINK_LOGIN);
    }
  }
});

export function useUserStoreWithOut() {
  return useUserStore(pinia);
}
